package org.rc.server;

import org.apache.commons.lang3.StringUtils;
import org.rc.cache.AudioBufferCache;
import org.rc.cache.AudioPcmClientCache;
import org.rc.cache.FrontPcmSessionCache;
import org.rc.client.AudioPcmClient;
import org.rc.config.WsSessionConfig;
import org.rc.util.RequestParamUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;

@ServerEndpoint(value = "/front-pcm", configurator = WsSessionConfig.class)
@Component
@Scope("prototype")
public class RemoteCommandPcmEndpoint {
    private static final Logger log = LoggerFactory.getLogger(RemoteCommandPcmEndpoint.class);

    @Value("${audio.pcm.endpoint}")
    private String audioPcmEndpoint;

    @Value("${audio.pcm.endpoint-dt3}")
    private String audioPcmEndpointDt3;

    @Value("${audio.package.size}")
    private int audioPackageSize;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) throws IOException {
        String param = session.getQueryString();
        Map<String, String> paramsMap = RequestParamUtil.regularParam2Map(param);
        String mac = paramsMap.get("mac");
        String version = paramsMap.get("version");
        log.info("接收到拉取音频pcm主接，mac--->{},version--->{}", mac, version);
        if (StringUtils.isEmpty(mac)) {
            log.warn("设备号为空，断开连接");
            session.getBasicRemote().sendText("设备号为空，断开连接");
            session.close();
            return;
        }
        session.getUserProperties().put("mac", mac);
        AudioPcmClient client = AudioPcmClientCache.getClient(mac);
        String dtVersion = paramsMap.get("version");
        if (null == client || client.getConnection() == null || !client.getConnection().isOpen()) {
            log.info("当前麦克风--->{}无拉取音频连接，开始建立连接.", mac);
            try {
                String curAudioPcmEndpoint = StringUtils.isNotBlank(dtVersion) && dtVersion.equals("3.0") ? audioPcmEndpointDt3 : audioPcmEndpoint;
                String audioPcmUri = curAudioPcmEndpoint + "?audioDevId=" + mac + "&headless=1&isOthers=1";
                URI uri = new URI(audioPcmUri);
                client = new AudioPcmClient(uri, mac, this.audioPackageSize, dtVersion);
                AudioPcmClientCache.saveClient(mac, client);
            } catch (Exception e) {
                log.error("和麦克风音频服务服务建立连接出现异常, e--->", e);
                AudioPcmClientCache.delClient(mac);
            }
        } else {
            log.info("当前麦克风转写请求连接已经建立");
        }
        FrontPcmSessionCache.add(mac, session);
    }

    @OnMessage
    public void onMessage(String text, Session session) throws IOException {
        String mac = session.getUserProperties().get("mac").toString();
        log.info("接收到设备--->{}，发送的文本--->{}", mac, text);
    }

    @OnClose
    public void onClose(Session session) {
        String mac = session.getUserProperties().get("mac").toString();
        FrontPcmSessionCache.removeSession(mac, session);
        List<Session> sessions = FrontPcmSessionCache.getSessions(mac);
        if (CollectionUtils.isEmpty(sessions)) {
            log.info("当前无任何请求音频客户端连接，关闭拉取文本连接");
            AudioPcmClientCache.delClient(mac);
            AudioBufferCache.clear(mac);
        }
    }

    @OnError
    public void onError(Session session, Throwable th) {
        log.error("连接发生异常,e---> ", th);
        String mac = session.getUserProperties().get("mac").toString();
        FrontPcmSessionCache.removeSession(mac, session);
        List<Session> sessions = FrontPcmSessionCache.getSessions(mac);
        if (CollectionUtils.isEmpty(sessions)) {
            log.info("当前无任何请求音频客户端连接，关闭拉取文本连接");
            AudioPcmClientCache.delClient(mac);
            AudioBufferCache.clear(mac);
        }
    }
}
